package com.huangyi.portalservice.homepage.service.impl;

import com.huangyi.adminapi.map.domain.vo.RegionVO;
import com.huangyi.adminapi.map.feign.MapFeignClient;
import com.huangyi.commoncore.utils.JsonUtil;
import com.huangyi.commondomain.domain.R;
import com.huangyi.commondomain.domain.ResultCode;
import com.huangyi.commonredis.service.RedisService;
import com.huangyi.portalservice.homepage.domain.dto.CityDescDTO;
import com.huangyi.portalservice.homepage.service.IRegionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 区域服务实现类
 * 
 * <p>提供区域数据的查询和缓存功能，支持根据父区域ID查询子区域列表
 * 
 * @author huangyi
 * @version 1.0
 * @since 2024
 */
@Component
@Slf4j
public class RegionServiceImpl implements IRegionService {

    private static final String REGION_CHILDREN_PREFIX = "applet:region:children:";
    private static final Long REGION_CHILDREN_TIMEOUT = 24 * 60L;

    @Autowired
    private MapFeignClient mapFeignClient;
    @Autowired
    private RedisService redisService;


    @Override
    public List<CityDescDTO> regionChildren(Long parentId) {
        if(parentId == null){
            log.error("城市id为空, 无法查询该城市下的子区域列表！");
            return Arrays.asList();
        }

        // 查询 Redis 缓存, 2级城市对3级区县 为 1 对 多, 字典服务会传入多个 1 对多的对象列表, 注意区分
        List<CityDescDTO> result = getCacheRegionList(parentId);
        if(!CollectionUtils.isEmpty(result)){
            // 如果查询到 Redis 缓存则直接返
            return result;
        }


        // 从 MySQL 中查询数据
        R<List<RegionVO>> listR =  mapFeignClient.regionChildren(parentId);
        if(listR == null || listR.getData() == null || listR.getCode() != ResultCode.SUCCESS.getCode()){
            log.error("获取父区域下的子区域列表失败！ parentId:{}", parentId);
            return Arrays.asList();
        }

        // 转换实例类并缓存进 Redis
        result = listR.getData().stream()
                        .map(regionVO -> {
                            CityDescDTO cityDescDTO = new CityDescDTO();
                            cityDescDTO.setId(regionVO.getId());
                            cityDescDTO.setName(regionVO.getName());
                            cityDescDTO.setFullName(regionVO.getFullName());
                            return cityDescDTO;
                        }).collect(Collectors.toList());
        cacheRegionList(parentId, result);

        // 返回结果
        return result;

    }

    private void cacheRegionList(Long parentId, List<CityDescDTO> regionList) {
        if (parentId == null) {
            return;
        }
        redisService.setCacheObject(REGION_CHILDREN_PREFIX + parentId, regionList,
                REGION_CHILDREN_TIMEOUT, TimeUnit.MINUTES);
    }

    private List<CityDescDTO> getCacheRegionList(Long parentId) {
        String str = redisService.getCacheObject(
                REGION_CHILDREN_PREFIX + parentId, String.class);
        if(StringUtils.isBlank(str)){
            return Arrays.asList();
        }

        return JsonUtil.string2List(str, CityDescDTO.class);
    }
}
